<?php

namespace App\Http\Controllers;

use App\Models\MoneyBook;
use App\Models\MoneyCategory;
use App\Models\MoneySubCategory;
use App\Models\AutoMoneyTransaction;
use App\Models\MoneyTransaction;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class AutoTransactionController extends Controller
{
    /**
     * 显示定时记账列表页面
     */
    public function index(Request $request)
    {
        $user = Auth::user();
        $bookId = $request->input('book_id', $user->default_book_id);
        $book = MoneyBook::find($bookId);

        if (!$book) {
            return redirect()->route('user.books')->with('error', '请先创建或选择一个账本');
        }

        // 检查用户是否有权限访问该账本
        if (!$book->users()->where('user_id', $user->id)->exists()) {
            return redirect()->route('user.books')->with('error', '您没有权限访问该账本');
        }

        // 获取分类数据
        $expenseCategories = MoneyCategory::where('book_id', $book->id)
            ->where('type', MoneyCategory::TYPE_EXPENSE)
            ->with('subCategories')
            ->orderBy('sort', 'asc')
            ->get();

        $incomeCategories = MoneyCategory::where('book_id', $book->id)
            ->where('type', MoneyCategory::TYPE_INCOME)
            ->with('subCategories')
            ->orderBy('sort', 'asc')
            ->get();

        return view('transaction.auto.index', [
            'book' => $book,
            'expenseCategories' => $expenseCategories,
            'incomeCategories' => $incomeCategories
        ]);
    }

    /**
     * 获取定时记账列表数据
     */
    public function getData(Request $request)
    {
        $user = Auth::user();
        $bookId = $request->input('book_id', $user->default_book_id);

        $autoTransactions = AutoMoneyTransaction::where('book_id', $bookId)
            ->where('user_id', $user->id)
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(function ($transaction) {
                return [
                    'id' => $transaction->id,
                    'title' => $transaction->title,
                    'type' => $transaction->type,
                    'type_text' => $transaction->type_text,
                    'amount' => $transaction->amount,
                    'category_name' => $transaction->category->name,
                    'category_icon' => $transaction->category->icon,
                    'sub_category_name' => $transaction->subCategory ? $transaction->subCategory->name : null,
                    'period_type' => $transaction->period_type,
                    'period_type_text' => $transaction->period_type_text,
                    'period_value' => $transaction->period_value,
                    'execute_time' => $transaction->execute_time ? $transaction->execute_time->format('H:i') : '09:00',
                    'start_date' => $transaction->start_date->format('Y-m-d'),
                    'end_date' => $transaction->end_date ? $transaction->end_date->format('Y-m-d') : null,
                    'status' => $transaction->status,
                    'status_text' => $transaction->status_text,
                    'next_execute_date' => $transaction->next_execute_date ? $transaction->next_execute_date->format('Y-m-d') : null,
                    'executed_count' => $transaction->executed_count,
                    'description' => $transaction->description,
                ];
            });

        return response()->json([
            'success' => true,
            'data' => $autoTransactions
        ]);
    }

    /**
     * 显示创建定时记账页面
     */
    public function create(Request $request)
    {
        $user = Auth::user();
        $bookId = $request->input('book_id', $user->default_book_id);
        $book = MoneyBook::find($bookId);

        if (!$book) {
            return redirect()->route('user.books')->with('error', '请先创建或选择一个账本');
        }

        // 检查用户是否有权限访问该账本
        if (!$book->users()->where('user_id', $user->id)->exists()) {
            return redirect()->route('user.books')->with('error', '您没有权限访问该账本');
        }

        // 获取分类数据
        $expenseCategories = MoneyCategory::where('book_id', $book->id)
            ->where('type', MoneyCategory::TYPE_EXPENSE)
            ->with('subCategories')
            ->orderBy('sort', 'asc')
            ->get();

        $incomeCategories = MoneyCategory::where('book_id', $book->id)
            ->where('type', MoneyCategory::TYPE_INCOME)
            ->with('subCategories')
            ->orderBy('sort', 'asc')
            ->get();

        return view('transaction.auto.create', [
            'book' => $book,
            'expenseCategories' => $expenseCategories,
            'incomeCategories' => $incomeCategories,
            'type' => request('type', 'expense'),
            'amount' => request('amount', ''),
            'category' => request('category', ''),
            'note' => request('note', ''),
        ]);
    }

    /**
     * 保存定时记账
     */
    public function store(Request $request)
    {
        $user = Auth::user();
        $bookId = $request->input('book_id', $user->default_book_id);

        // 验证账本是否存在且用户有权限
        $book = MoneyBook::find($bookId);
        if (!$book || !$book->users()->where('user_id', $user->id)->exists()) {
            return response()->json([
                'success' => false,
                'message' => '无效的账本或您没有权限'
            ], 403);
        }

        // 检查非会员用户的定时记账数量限制
        if (!$user->isMember()) {
            $currentCount = AutoMoneyTransaction::where('user_id', $user->id)
                ->where('status', AutoMoneyTransaction::STATUS_ENABLED)
                ->count();

            $maxAllowed = non_member_limits['max_record_by_cron'];

            if ($currentCount >= $maxAllowed) {
                return response()->json([
                    'success' => false,
                    'message' => '非会员用户最多只能创建'.$maxAllowed.'个定时记账',
                    'redirect_to' => route('membership.benefits')
                ], 403);
            }
        }

        $validator = Validator::make($request->all(), [
            'type' => 'required|in:income,expense',
            'amount' => 'required|numeric|min:0.01',
            'category_id' => 'required|exists:money_categories,id',
            'sub_category_id' => 'nullable|exists:money_sub_categories,id',
            'title' => 'required|string|max:100',
            'description' => 'nullable|string|max:255',
            'period_type' => 'required|integer|in:1,2,3,4',
            'period_value' => 'required_if:period_type,2,3|nullable|integer|min:1|max:1231',
            'execute_time' => 'required|date_format:H:i',
            'start_date' => 'required|date',
            'end_date' => 'nullable|date|after_or_equal:start_date',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors()
            ], 422);
        }

        // 验证分类和子分类是否匹配
        $categoryId = $request->input('category_id');
        $subCategoryId = $request->input('sub_category_id');

        if ($subCategoryId) {
            $subCategory = MoneySubCategory::find($subCategoryId);
            if (!$subCategory || $subCategory->category_id != $categoryId) {
                return response()->json([
                    'success' => false,
                    'message' => '子分类与主分类不匹配'
                ], 422);
            }
        }

        // 获取分类类型
        $category = MoneyCategory::find($categoryId);
        $type = $category->type;

        // 计算下次执行日期
        $startDate = Carbon::parse($request->input('start_date'));
        $executeTime = $request->input('execute_time');
        $periodType = $request->input('period_type');
        $periodValue = $request->input('period_value');

        // 创建定时记账记录
        $autoTransaction = new AutoMoneyTransaction();
        $autoTransaction->book_id = $bookId;
        $autoTransaction->user_id = $user->id;
        $autoTransaction->category_id = $categoryId;
        $autoTransaction->sub_category_id = $subCategoryId;
        $autoTransaction->type = $type;
        $autoTransaction->amount = $request->input('amount');
        $autoTransaction->title = $request->input('title');
        $autoTransaction->description = $request->input('description');
        $autoTransaction->period_type = $periodType;
        $autoTransaction->period_value = $periodValue;
        $autoTransaction->execute_time = $executeTime;
        $autoTransaction->start_date = $startDate;
        $autoTransaction->end_date = $request->input('end_date');
        $autoTransaction->status = AutoMoneyTransaction::STATUS_ENABLED;

        // 计算下次执行日期
        $autoTransaction->next_execute_date = $autoTransaction->calculateNextExecuteDate($startDate);

        $autoTransaction->save();

        return response()->json([
            'success' => true,
            'message' => '定时记账创建成功',
            'data' => $autoTransaction
        ]);
    }

    /**
     * 显示编辑定时记账页面
     */
    public function edit($id)
    {
        $user = Auth::user();
        $autoTransaction = AutoMoneyTransaction::where('id', $id)
            ->where('user_id', $user->id)
            ->firstOrFail();

        $book = $autoTransaction->book;

        // 获取分类数据
        $expenseCategories = MoneyCategory::where('book_id', $book->id)
            ->where('type', MoneyCategory::TYPE_EXPENSE)
            ->with('subCategories')
            ->orderBy('sort', 'asc')
            ->get();

        $incomeCategories = MoneyCategory::where('book_id', $book->id)
            ->where('type', MoneyCategory::TYPE_INCOME)
            ->with('subCategories')
            ->orderBy('sort', 'asc')
            ->get();

        return view('transaction.auto.edit', [
            'autoTransaction' => $autoTransaction,
            'book' => $book,
            'expenseCategories' => $expenseCategories,
            'incomeCategories' => $incomeCategories,
        ]);
    }

    /**
     * 更新定时记账
     */
    public function update(Request $request, $id)
    {
        $user = Auth::user();
        $autoTransaction = AutoMoneyTransaction::where('id', $id)
            ->where('user_id', $user->id)
            ->firstOrFail();

        // 验证并获取账本
        $bookId = $request->input('book_id', $autoTransaction->book_id);
        $book = MoneyBook::find($bookId);

        // 验证账本是否存在且用户有权限
        if (!$book || !$book->users()->where('user_id', $user->id)->exists()) {
            return response()->json([
                'success' => false,
                'message' => '账本不存在或您没有权限'
            ], 403);
        }

        $validator = Validator::make($request->all(), [
            'type' => 'required|in:income,expense',
            'amount' => 'required|numeric|min:0.01',
            'category_id' => 'required|exists:money_categories,id',
            'sub_category_id' => 'nullable|exists:money_sub_categories,id',
            'title' => 'required|string|max:100',
            'description' => 'nullable|string|max:255',
            'period_type' => 'required|integer|in:1,2,3,4',
            'period_value' => 'required_if:period_type,2,3|nullable|integer|min:1|max:1231',
            'execute_time' => 'required|date_format:H:i',
            'start_date' => 'required|date',
            'end_date' => 'nullable|date|after_or_equal:start_date',
//            'status' => 'nullable|boolean',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors()
            ], 422);
        }

        // 验证分类和子分类是否匹配
        $categoryId = $request->input('category_id');
        $subCategoryId = $request->input('sub_category_id');

        if ($subCategoryId) {
            $subCategory = MoneySubCategory::find($subCategoryId);
            if (!$subCategory || $subCategory->category_id != $categoryId) {
                return response()->json([
                    'success' => false,
                    'message' => '子分类与主分类不匹配'
                ], 422);
            }
        }

        // 获取分类类型
        $category = MoneyCategory::find($categoryId);
        $type = $category->type;

        // 更新定时记账记录
        $autoTransaction->book_id = $bookId;
        $autoTransaction->category_id = $categoryId;
        $autoTransaction->sub_category_id = $subCategoryId;
        $autoTransaction->type = $type;
        $autoTransaction->amount = $request->input('amount');
        $autoTransaction->title = $request->input('title');
        $autoTransaction->description = $request->input('description');
        $autoTransaction->period_type = $request->input('period_type');
        $autoTransaction->period_value = $request->input('period_value');
        $autoTransaction->execute_time = $request->input('execute_time');
        $autoTransaction->start_date = $request->input('start_date');
        $autoTransaction->end_date = $request->input('end_date');
//        $autoTransaction->status = $request->input('status');

        // 检查当前周期是否已经记录过
        $currentDate = Carbon::now();
        $shouldCheckExisting = false;
        
        // 如果修改了关键参数（周期类型、周期值、开始日期），需要检查是否已有记录
        if ($autoTransaction->period_type != $request->input('period_type') ||
            $autoTransaction->period_value != $request->input('period_value') ||
            $autoTransaction->start_date->format('Y-m-d') != $request->input('start_date')) {
            $shouldCheckExisting = true;
        }

        // 重新计算下次执行日期
        $startDate = Carbon::parse($request->input('start_date'));
        $newNextExecuteDate = $autoTransaction->calculateNextExecuteDate($startDate);
        
        // 如果需要检查现有记录，且当前日期在执行范围内
        if ($shouldCheckExisting && $currentDate->gte($startDate)) {
            // 根据周期类型检查当前周期是否已有记录
            $periodType = $request->input('period_type');
            $hasExistingRecord = false;
            
            switch ($periodType) {
                case AutoMoneyTransaction::PERIOD_DAILY:
                    // 每日：检查今天是否已有记录
                    $hasExistingRecord = MoneyTransaction::where('auto_money_transaction_id', $autoTransaction->id)
                        ->where('transaction_date', $currentDate->format('Y-m-d'))
                        ->exists();
                    break;
                    
                case AutoMoneyTransaction::PERIOD_WEEKLY:
                    // 每周：检查本周是否已有记录
                    $weekStart = $currentDate->copy()->startOfWeek();
                    $weekEnd = $currentDate->copy()->endOfWeek();
                    $hasExistingRecord = MoneyTransaction::where('auto_money_transaction_id', $autoTransaction->id)
                        ->whereBetween('transaction_date', [$weekStart->format('Y-m-d'), $weekEnd->format('Y-m-d')])
                        ->exists();
                    break;
                    
                case AutoMoneyTransaction::PERIOD_MONTHLY:
                    // 每月：检查本月是否已有记录
                    $monthStart = $currentDate->copy()->startOfMonth();
                    $monthEnd = $currentDate->copy()->endOfMonth();
                    $hasExistingRecord = MoneyTransaction::where('auto_money_transaction_id', $autoTransaction->id)
                        ->whereBetween('transaction_date', [$monthStart->format('Y-m-d'), $monthEnd->format('Y-m-d')])
                        ->exists();
                    break;
                    
                case AutoMoneyTransaction::PERIOD_YEARLY:
                    // 每年：检查今年是否已有记录
                    $yearStart = $currentDate->copy()->startOfYear();
                    $yearEnd = $currentDate->copy()->endOfYear();
                    $hasExistingRecord = MoneyTransaction::where('auto_money_transaction_id', $autoTransaction->id)
                        ->whereBetween('transaction_date', [$yearStart->format('Y-m-d'), $yearEnd->format('Y-m-d')])
                        ->exists();
                    break;
            }
            
            // 如果当前周期已有记录，且新的计算结果显示当前周期应该执行，则跳过到下个周期
            if ($hasExistingRecord && $this->isInCurrentPeriod($newNextExecuteDate, $currentDate, $periodType)) {
                // 计算下个周期的执行日期
                $nextPeriodStart = $this->getNextPeriodStart($currentDate, $periodType);
                $newNextExecuteDate = $autoTransaction->calculateNextExecuteDate($nextPeriodStart);
            }
        }
        
        $autoTransaction->next_execute_date = $newNextExecuteDate;

        $autoTransaction->save();

        return response()->json([
            'success' => true,
            'message' => '定时记账更新成功',
            'data' => $autoTransaction
        ]);
    }

    /**
     * 切换定时记账状态
     */
    public function toggleStatus(Request $request, $id)
    {
        $autoTransaction = AutoMoneyTransaction::findOrFail($id);

        // 验证用户权限
        if ($autoTransaction->user_id !== auth()->id()) {
            return response()->json([
                'success' => false,
                'message' => '您没有权限操作此定时记账'
            ], 403);
        }

        // 如果是要启用定时记账，检查非会员用户的定时记账数量限制
        $user = auth()->user();
        if ($autoTransaction->status === AutoMoneyTransaction::STATUS_DISABLED &&
            !$user->isMember()) {

            $currentCount = AutoMoneyTransaction::where('user_id', $user->id)
                ->where('status', AutoMoneyTransaction::STATUS_ENABLED)
                ->count();

            $maxAllowed = non_member_limits['max_record_by_cron'];

            if ($currentCount >= $maxAllowed) {
                return response()->json([
                    'success' => false,
                    'message' => '非会员用户最多只能启用'.$maxAllowed.'个定时记账',
                    'redirect_to' => route('membership.benefits')
                ], 403);
            }
        }

        // 切换状态
        $autoTransaction->status = $autoTransaction->status === AutoMoneyTransaction::STATUS_ENABLED
            ? AutoMoneyTransaction::STATUS_DISABLED
            : AutoMoneyTransaction::STATUS_ENABLED;

        // 如果启用，重新计算下次执行日期
        if ($autoTransaction->status === AutoMoneyTransaction::STATUS_ENABLED) {
            $autoTransaction->next_execute_date = $autoTransaction->calculateNextExecuteDate();
        }

        $autoTransaction->save();

        return response()->json([
            'success' => true,
            'status' => $autoTransaction->status,
            'message' => '状态已更新',
            'status_text' => $autoTransaction->status_text
        ]);
    }

    /**
     * 删除定时记账
     */
    public function destroy($id)
    {
        $user = Auth::user();
        $autoTransaction = AutoMoneyTransaction::where('id', $id)
            ->where('user_id', $user->id)
            ->firstOrFail();

        $autoTransaction->delete();

        return response()->json([
            'success' => true,
            'message' => '定时记账已删除'
        ]);
    }

    /**
     * 检查指定日期是否在当前周期内
     */
    private function isInCurrentPeriod($targetDate, $currentDate, $periodType)
    {
        switch ($periodType) {
            case AutoMoneyTransaction::PERIOD_DAILY:
                return $targetDate->isSameDay($currentDate);
                
            case AutoMoneyTransaction::PERIOD_WEEKLY:
                return $targetDate->weekOfYear == $currentDate->weekOfYear && 
                       $targetDate->year == $currentDate->year;
                       
            case AutoMoneyTransaction::PERIOD_MONTHLY:
                return $targetDate->month == $currentDate->month && 
                       $targetDate->year == $currentDate->year;
                       
            case AutoMoneyTransaction::PERIOD_YEARLY:
                return $targetDate->year == $currentDate->year;
                
            default:
                return false;
        }
    }

    /**
     * 获取下个周期的开始日期
     */
    private function getNextPeriodStart($currentDate, $periodType)
    {
        switch ($periodType) {
            case AutoMoneyTransaction::PERIOD_DAILY:
                return $currentDate->copy()->addDay();
                
            case AutoMoneyTransaction::PERIOD_WEEKLY:
                return $currentDate->copy()->addWeek()->startOfWeek();
                
            case AutoMoneyTransaction::PERIOD_MONTHLY:
                return $currentDate->copy()->addMonth()->startOfMonth();
                
            case AutoMoneyTransaction::PERIOD_YEARLY:
                return $currentDate->copy()->addYear()->startOfYear();
                
            default:
                return $currentDate->copy()->addDay();
        }
    }
}
